package com.metaaps.eoraster;

import it.geosolutions.imageio.plugins.tiff.TIFFImageReadParam;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * A class that reads Radarsat 2 SLC images
 * @author gabbaan
 */
public class Radarsat2Image_SLC extends Radarsat2Image {

    private int[] preloadedDataReal;
    private int[] preloadedDataImg;

    // <editor-fold defaultstate="collapsed" desc=" UML Marker ">
    // #[regen=yes,id=DCE.4A46CCF6-E120-452D-098F-D6C37C7B5C56]
    // </editor-fold> 
    public Radarsat2Image_SLC() {
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.C96C2CB4-F58B-E9CA-5017-A116AD5A64C4]
    // </editor-fold> 
    @Override
    public boolean initialise() {
        if (tiffImages == null) {
            return false;
        }
        try {
            image = tiffImages.values().iterator().next();
            xSize = image.reader.getWidth(0);//pixels per line
            ySize = image.reader.getHeight(0);
            bounds = new Rectangle(0, 0, xSize, ySize);

        } catch (IOException ex) {
            dispose();
            //Logger.getLogger(Radarsat2Image.class.getName()).log(Level.SEVERE, null, ex);
            return false;
        }
        return true;
    }

    @Override
    public int[] readTile(int x, int y, int width, int height) {

        Rectangle rect = new Rectangle(x, y, width, height);
        rect = rect.intersection(bounds);
        int[] tile = new int[height * width];
        if (rect.isEmpty()) {
            return tile;
        }
        if (rect.y != preloadedInterval[0] | rect.y + rect.height != preloadedInterval[1]) {
            preloadLineTile(rect.y, rect.height);
        }
        int yOffset = xSize;
        int xinit = rect.x - x;
        int yinit = rect.y - y;
        for (int i = 0; i < rect.height; i++) {
            for (int j = 0; j < rect.width; j++) {
                int temp = i * yOffset + j + rect.x;
                long real=preloadedDataReal[temp];
                long img=preloadedDataImg[temp];
                tile[(i + yinit) * width + j + xinit] = (int)Math.sqrt(real*real+img*img);
            }
        }
        return tile;
    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.091BEB3C-7DA3-1625-A9FA-3CED510139EC]
    // </editor-fold> 
    @Override
    public int read(int x, int y) {
        TIFFImageReadParam t = new TIFFImageReadParam();
        t.setSourceRegion(new Rectangle(x, y, 1, 1));
        try {            
            int img = image.reader.read(0, t).getRaster().getSample(x, y, 1);
            int real = image.reader.read(0, t).getRaster().getSample(x, y, 0);
            return (int) Math.sqrt(real * real + img * img);

        } catch (IOException ex) {
            Logger.getLogger(GeotiffImage.class.getName()).log(Level.SEVERE, null, ex);
        }
        return -1;

    }

    // <editor-fold defaultstate="collapsed" desc=" UML Marker "> 
    // #[regen=yes,id=DCE.A95D94A3-4A56-4C07-ACBE-58BE24845725]
    // </editor-fold> 
    @Override
    public void preloadLineTile(int y, int length) {
        if (y < 0) {
            return;
        }
        preloadedInterval = new int[]{y, y + length};
        Rectangle rect = new Rectangle(0, y, xSize, length);
        TIFFImageReadParam tirp = new TIFFImageReadParam();
        tirp.setSourceRegion(rect);
       
        try {
            preloadedDataReal = image.reader.read(0, tirp).getRaster().getSamples(0, 0, xSize, length, 0, (int[]) null);
            preloadedDataImg = image.reader.read(0, tirp).getRaster().getSamples(0, 0, xSize, length, 1, (int[]) null);
        } catch (Exception ex) {
            Logger.getLogger(GeotiffImage.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    @Override
    public int getNumberOfBytes() {
        return 4;
    }

    @Override
    public int getType(boolean oneBand) {
        if (oneBand || bands.size() < 2) {
            return BufferedImage.TYPE_USHORT_GRAY;
        } else {
            return BufferedImage.TYPE_INT_RGB;
        }
    }

    @Override
    public String getFormat() {
        return getClass().getCanonicalName();
    }
}

